package com.rd.animation.type;

import com.rd.animation.controller.ValueController;
import com.rd.animation.data.type.ColorAnimationValue;
import com.rd.utils.AnimatorUtils;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;

public class ColorAnimation extends BaseAnimation<ValueAnimator> {
    public static final String DEFAULT_UNSELECTED_COLOR = "#33ffffff";
    public static final String DEFAULT_SELECTED_COLOR = "#ffffff";

    static final String ANIMATION_COLOR_REVERSE = "ANIMATION_COLOR_REVERSE";
    static final String ANIMATION_COLOR = "ANIMATION_COLOR";
    int colorStart;
    int colorEnd;
    private ColorAnimationValue value;

    private int color;
    private int colorReverse;

    public ColorAnimation(ValueController.UpdateListener listener) {
        super(listener);
        value = new ColorAnimationValue();
    }

    @Override
    public ValueAnimator createAnimator() {
        ValueAnimator animator = new ValueAnimator();
        animator.setDuration(BaseAnimation.DEFAULT_ANIMATION_TIME);
        animator.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        animator.setValueUpdateListener(
                new AnimatorValue.ValueUpdateListener() {
                    @Override
                    public void onUpdate(AnimatorValue animatorValue, float v) {
                        animator.onUpdate(animatorValue, v);
                        onAnimateUpdated(animatorValue);
                    }
                });

        return animator;
    }

    @Override
    public ColorAnimation progress(float progress) {
        if (animator != null) {
            long playTime = (long) (progress * animationDuration);

            animator.onUpdate(animator, AnimatorUtils.getInterpolation(progress));
            onAnimateUpdated(animator);
        }

        return this;
    }

    public ColorAnimation with(int colorStart, int colorEnd) {
        if (animator != null && hasChanges(colorStart, colorEnd)) {
            this.colorStart = colorStart;
            this.colorEnd = colorEnd;
            PropertyValuesHolder holder = createColorPropertyHolder(false);
            PropertyValuesHolder holderReverse = createColorPropertyHolder(true);

            animator.setInnerListener(
                    new InnerValueUpdateListener() {
                        @Override
                        public void onUpdate(AnimatorValue animatorValue, float f) {
                            color = AnimatorUtils.getColor(f, holder.getStartValue(), holder.getEndValue());
                            colorReverse =
                                    AnimatorUtils.getColor(
                                            f, holderReverse.getStartValue(), holderReverse.getEndValue());
                        }
                    });
        }

        return this;
    }

    PropertyValuesHolder createColorPropertyHolder(boolean isReverse) {
        int colorStart;
        int colorEnd;

        if (isReverse) {
            colorStart = this.colorEnd;
            colorEnd = this.colorStart;

        } else {
            colorStart = this.colorStart;
            colorEnd = this.colorEnd;
        }

        PropertyValuesHolder holder = PropertyValuesHolder.ofInt(colorStart, colorEnd);
        return holder;
    }

    @SuppressWarnings("RedundantIfStatement")
    private boolean hasChanges(int colorStart, int colorEnd) {
        if (this.colorStart != colorStart) {
            return true;
        }

        if (this.colorEnd != colorEnd) {
            return true;
        }

        return false;
    }

    private void onAnimateUpdated(AnimatorValue animation) {
        value.setColor(color);
        value.setColorReverse(colorReverse);

        if (listener != null) {
            listener.onValueUpdated(value);
        }
    }
}
